{
 "cells": [
  {
   "cell_type": "markdown",
   "source": [
    "asyncio 是 Python 标准库中的一个模块，用于编写异步 I/O 和并发代码。它提供了一种简单的方式来编写单线程并发代码，利用协程、任务和事件循环来管理异步操作。以下是 asyncio 的详细讲解：\n",
    "\n",
    "# 基本概念\n",
    "1. 协程 (Coroutine)\n",
    "- 协程是一种特殊的函数，可以暂停执行并在稍后恢复。使用 async def 定义协程。\n",
    "- 协程不能直接运行，需要通过事件循环或其他异步机制来调度。\n",
    "\n",
    "2. 事件循环 (Event Loop)\n",
    "- 事件循环是 asyncio 的核心，负责管理和调度协程。\n",
    "- 使用 asyncio.run() 或 asyncio.get_event_loop() 获取事件循环。\n",
    "\n",
    "3. 任务 (Task)\n",
    "- 任务是 asyncio 中的可等待对象，用于包装协程并将其注册到事件循环中。\n",
    "- 使用 asyncio.create_task() 创建任务。\n",
    "\n",
    "4. Future\n",
    "- Future 是一个特殊类型的可等待对象，表示一个最终会完成的操作的结果。\n",
    "- 通常由库内部创建，用于表示异步操作的结果。\n",
    "\n",
    "\n",
    "## 基本用例\n",
    "异步函数使用async def声明，await关键字用于等待一个异步操作完成。例如："
   ],
   "metadata": {
    "collapsed": false
   },
   "id": "37f86894f8fad0ed"
  },
  {
   "cell_type": "code",
   "outputs": [
    {
     "ename": "RuntimeError",
     "evalue": "asyncio.run() cannot be called from a running event loop",
     "output_type": "error",
     "traceback": [
      "\u001B[0;31m---------------------------------------------------------------------------\u001B[0m",
      "\u001B[0;31mRuntimeError\u001B[0m                              Traceback (most recent call last)",
      "Cell \u001B[0;32mIn[2], line 18\u001B[0m\n\u001B[1;32m     14\u001B[0m         tg\u001B[38;5;241m.\u001B[39mcreate_task(task(\u001B[38;5;241m2\u001B[39m))\n\u001B[1;32m     15\u001B[0m         tg\u001B[38;5;241m.\u001B[39mcreate_task(task(\u001B[38;5;241m3\u001B[39m))\n\u001B[0;32m---> 18\u001B[0m asyncio\u001B[38;5;241m.\u001B[39mrun(main())\n\u001B[1;32m     21\u001B[0m \u001B[38;5;124;03m\"\"\"\u001B[39;00m\n\u001B[1;32m     22\u001B[0m \u001B[38;5;124;03m输出：\u001B[39;00m\n\u001B[1;32m     23\u001B[0m \u001B[38;5;124;03m任务 1 启动 17:08:18\u001B[39;00m\n\u001B[0;32m   (...)\u001B[0m\n\u001B[1;32m     28\u001B[0m \u001B[38;5;124;03m任务 3 结束 17:08:20\u001B[39;00m\n\u001B[1;32m     29\u001B[0m \u001B[38;5;124;03m\"\"\"\u001B[39;00m\n",
      "File \u001B[0;32m/opt/anaconda3/envs/ai_312/lib/python3.12/asyncio/runners.py:190\u001B[0m, in \u001B[0;36mrun\u001B[0;34m(main, debug, loop_factory)\u001B[0m\n\u001B[1;32m    161\u001B[0m \u001B[38;5;250m\u001B[39m\u001B[38;5;124;03m\"\"\"Execute the coroutine and return the result.\u001B[39;00m\n\u001B[1;32m    162\u001B[0m \n\u001B[1;32m    163\u001B[0m \u001B[38;5;124;03mThis function runs the passed coroutine, taking care of\u001B[39;00m\n\u001B[0;32m   (...)\u001B[0m\n\u001B[1;32m    186\u001B[0m \u001B[38;5;124;03m    asyncio.run(main())\u001B[39;00m\n\u001B[1;32m    187\u001B[0m \u001B[38;5;124;03m\"\"\"\u001B[39;00m\n\u001B[1;32m    188\u001B[0m \u001B[38;5;28;01mif\u001B[39;00m events\u001B[38;5;241m.\u001B[39m_get_running_loop() \u001B[38;5;129;01mis\u001B[39;00m \u001B[38;5;129;01mnot\u001B[39;00m \u001B[38;5;28;01mNone\u001B[39;00m:\n\u001B[1;32m    189\u001B[0m     \u001B[38;5;66;03m# fail fast with short traceback\u001B[39;00m\n\u001B[0;32m--> 190\u001B[0m     \u001B[38;5;28;01mraise\u001B[39;00m \u001B[38;5;167;01mRuntimeError\u001B[39;00m(\n\u001B[1;32m    191\u001B[0m         \u001B[38;5;124m\"\u001B[39m\u001B[38;5;124masyncio.run() cannot be called from a running event loop\u001B[39m\u001B[38;5;124m\"\u001B[39m)\n\u001B[1;32m    193\u001B[0m \u001B[38;5;28;01mwith\u001B[39;00m Runner(debug\u001B[38;5;241m=\u001B[39mdebug, loop_factory\u001B[38;5;241m=\u001B[39mloop_factory) \u001B[38;5;28;01mas\u001B[39;00m runner:\n\u001B[1;32m    194\u001B[0m     \u001B[38;5;28;01mreturn\u001B[39;00m runner\u001B[38;5;241m.\u001B[39mrun(main)\n",
      "\u001B[0;31mRuntimeError\u001B[0m: asyncio.run() cannot be called from a running event loop"
     ]
    }
   ],
   "source": [
    "import asyncio\n",
    "import time\n",
    "\n",
    "\n",
    "async def task(n):\n",
    "    print(f\"任务 {n} 启动 {time.strftime('%X')}\")\n",
    "    await asyncio.sleep(2)\n",
    "    print(f\"任务 {n} 结束 {time.strftime('%X')}\")\n",
    "\n",
    "\n",
    "async def main():\n",
    "    async with asyncio.TaskGroup() as tg:\n",
    "        tg.create_task(task(1))\n",
    "        tg.create_task(task(2))\n",
    "        tg.create_task(task(3))\n",
    "\n",
    "\n",
    "asyncio.run(main())\n",
    "\n",
    "\n",
    "\"\"\"\n",
    "输出：\n",
    "任务 1 启动 17:08:18\n",
    "任务 2 启动 17:08:18\n",
    "任务 3 启动 17:08:18\n",
    "任务 1 结束 17:08:20\n",
    "任务 2 结束 17:08:20\n",
    "任务 3 结束 17:08:20\n",
    "\"\"\"\n"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-11-07T09:25:19.249771Z",
     "start_time": "2024-11-07T09:25:19.221952Z"
    }
   },
   "id": "ae3e6bb57cf0ba04",
   "execution_count": 2
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
